package com.wuze.cloud.handler;

import com.wuze.cloud.dao.SysFileDao;
import com.wuze.cloud.dao.SysFolderDao;
import com.wuze.cloud.dao.SysFolderRelationDao;
import com.wuze.cloud.dao.SysRecyclingDao;
import com.wuze.cloud.pojo.SysFileDO;
import com.wuze.cloud.pojo.SysFolderRelationDO;
import com.wuze.cloud.pojo.SysRecyclingDO;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.assertj.core.util.Sets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static com.wuze.cloud.enums.SysFileTypeEnum.FOLDER_FILE;
import static com.wuze.cloud.enums.SysStateEnum.DELETE;
import static com.wuze.cloud.enums.SysStateEnum.RECYCLING;

/**
 * @Author wuze
 * @Date 2023/5/16 11:06
 * @ClassName: SysCleanRecycling
 * @Description: TODO
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class SysCleanRecycling {

    @Autowired
    private SysRecyclingDao recyclingDao;

    @Autowired
    private SysFileDao fileDao;

    @Autowired
    private SysFolderDao folderDao;
    @Autowired
    private SysFolderRelationDao folderRelationDao;

    @XxlJob("doCleanRecycling")
    @Transactional(rollbackFor = Exception.class)
    public ReturnT<String> doCleanRecycling() {
        log.info("---------开始执行清理回收站过期文件--------");
        List<SysRecyclingDO> recyclings = recyclingDao.findListByState(RECYCLING.name());
        List<Long> fileIds = Lists.newArrayList();
        List<Long> folderIds = Lists.newArrayList();
        //提取回收站文件和文件夹ID
        recyclings.forEach(recycling->{
            if(Objects.nonNull(recycling.getFileId())){
                fileIds.add(recycling.getFileId());
            }else {
                folderIds.add(recycling.getFolderId());
            }
        });
        log.info("回收站文件:{}",fileIds);
        log.info("回收站文件夹:{}",folderIds);
        deleteRecycling(fileIds, folderIds);

        return ReturnT.SUCCESS;
    }

    /**
     * 执行删除
     * @param fileIds
     * @param folderIds
     */
    private void deleteRecycling(List<Long> fileIds, List<Long> folderIds) {
        if(!CollectionUtils.isEmpty(fileIds)){
            fileDao.batchUpdateFileState(Sets.newHashSet(fileIds), DELETE.name());
            folderRelationDao.batchUpdateState(Sets.newHashSet(fileIds),DELETE.name());
            recyclingDao.batchDelByFileIdsAdmin(fileIds);
        }
        //获取所有文件夹id
        List<Long> ids = getFolderIdsByFolderIds(folderIds);
        Set<Long> set = Sets.newHashSet();
        if(!CollectionUtils.isEmpty(ids)){
            //获取所有文件id
            List<SysFileDO> allFiles = fileDao.findByFolderIdsAdmin(ids, RECYCLING.name());
            if(!CollectionUtils.isEmpty(allFiles)){
                set = allFiles.stream().map(SysFileDO::getId).collect(Collectors.toSet());
                fileDao.batchUpdateFileState(set, DELETE.name());
                folderRelationDao.batchUpdateState(set,DELETE.name());
            }
            folderRelationDao.batchUpdateState(Sets.newHashSet(ids), DELETE.name());
            folderDao.batchUpdateFolderState(ids,DELETE.name());
            recyclingDao.batchDelByFolderIdsAdmin(folderIds);
        }
        set.addAll(fileIds);
        log.info("总文件数：{}===fileIds:{}",set.size(),set);
        log.info("总文件夹数：{}===folderIds{}",ids.size(),ids);
    }

    /**
     * 获取文件夹及所有子文件夹id
     * @param folderIds
     * @return
     */
    private List<Long> getFolderIdsByFolderIds(List<Long> folderIds){
        List<Long> result = Lists.newArrayList();
        if(CollectionUtils.isEmpty(folderIds)){
            return result;
        }
        result.addAll(folderIds);
        List<SysFolderRelationDO> relationDOS = folderRelationDao.findByPids(folderIds, FOLDER_FILE.name(),RECYCLING.name());
        if(CollectionUtils.isEmpty(relationDOS)){
            return result;
        }
        List<Long> ids = relationDOS.stream().map(SysFolderRelationDO::getChildId).collect(Collectors.toList());
        result.addAll(getFolderIdsByFolderIds(ids));
        return result;
    }
}
